import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;

import common.Command;

enum MovePacket {
	DX, DY, TIMESTAMP
}

public class CommunicationProtocol {

	private static Robot r = null;
	private static final int SCROOL_REDUCTION_FACTOR = 3;

	private static long lastMoveTimestamp = 0;

	private static Robot getRobot() {
		if (r == null) {
			try {
				r = new Robot();
			} catch (AWTException e) {
				e.printStackTrace();
			}
		}
		return r;
	}

	public static void perform(Command c) {

		switch (c.getType()) {
		case LEFT_CLICK:
			performLeftClick();
			break;
		case RIGHT_CLICK:
			performRightClick();
			break;
		case MOVE:
			// System.out.println("MOVE");
			String value = c.getValue();
			performMove(Integer.parseInt(value.split(",")[MovePacket.DX
					.ordinal()]), Integer
					.parseInt(value.split(",")[MovePacket.DY.ordinal()]),
					Long.parseLong(value.split(",")[MovePacket.TIMESTAMP
							.ordinal()]));
			break;
		case SCROLL:
			int wheelRotation = Integer.parseInt(c.getValue());
			int scroll = wheelRotation / SCROOL_REDUCTION_FACTOR;
			if(scroll==0)
				scroll = wheelRotation;
			performScroll(scroll);
			break;
		case CLICK_MOVE:
			performClickMove(c.getValue());
			break;
		default:
			break;

		}

	}

	private static void performClickMove(String command) {
		Robot r = getRobot();
		if (command.equals("UP"))
			r.mouseRelease(InputEvent.BUTTON1_MASK);
		else if (command.equals("DOWN"))
			r.mousePress(InputEvent.BUTTON1_MASK);
	}

	private static void performRightClick() {
		Robot r = getRobot();
		r.mousePress(InputEvent.BUTTON3_MASK);
		r.mouseRelease(InputEvent.BUTTON3_MASK);

	}

	private static void performLeftClick() {
		Robot r = getRobot();
		r.mousePress(InputEvent.BUTTON1_MASK);
		r.mouseRelease(InputEvent.BUTTON1_MASK);
	}

	private static void performMove(int dx, int dy, long timestamp) {
		long timeStampDiff = timestamp - lastMoveTimestamp;
		lastMoveTimestamp = timestamp;
		if (timeStampDiff > 0) {
			Robot r = getRobot();

			Rectangle screen = new Rectangle(Toolkit.getDefaultToolkit()
					.getScreenSize());

			int x = MouseInfo.getPointerInfo().getLocation().x + dx;
			int y = MouseInfo.getPointerInfo().getLocation().y + dy;

			if (screen.contains(x, y))
				r.mouseMove(x, y);
		}
	}

	/**
	 * 
	 * @param wheelRotation
	 *            positivo verso basso, negativo verso alto
	 */
	private static void performScroll(int wheelRotation) {
		Robot r = getRobot();
		r.mouseWheel(wheelRotation);
	}
}
